package com.hly.musicbackground.model.auth.service.impl;

import com.hly.musicbackground.Final.RedisFinal;
import com.hly.musicbackground.Utils.RedisUtil;
import com.hly.musicbackground.Utils.RequestContextUtils;
import com.hly.musicbackground.Utils.ThreadPoolUtils;
import com.hly.musicbackground.exception.ExceptionMail;
import com.hly.musicbackground.model.auth.service.IPService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class IPServiceImpl implements IPService {

    private final RedisUtil redisUtil;
    private final StringRedisTemplate stringRedisTemplate;
    private final ExceptionMail exceptionMail;

    @Value("${IPService.ttl}")
    private Long ttl;
    @Value("${IPService.num}")
    private Long num;

    @Override
    public boolean ifIPAddress(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        String ipAddress = RequestContextUtils.getIPAddress();

        if (stringRedisTemplate.hasKey(RedisFinal.DISABLE_IP_ADDRESS + ipAddress))
            return true;

        String requestURI = httpServletRequest.getRequestURI();
        String key = RedisFinal.TEMPORARY_IP_URL + ipAddress + ":" + requestURI;

        Long increment = stringRedisTemplate.opsForValue().increment(key);
        if (increment > num){
            if (increment == num + 1){
                redisUtil.set(RedisFinal.DISABLE_IP_ADDRESS + ipAddress, "1", 1L, TimeUnit.HOURS);
                exceptionMail.sendMails("警告：有人恶意攻击", ipAddress + requestURI);
            }
            return true;
        }
        stringRedisTemplate.expire(key, ttl, TimeUnit.SECONDS);
        return false;
    }
}
